﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AddIn.EA.Architecture.ComponentLogic.ElementModel;

namespace AddIn.EA.Architecture.ComponentLogic.StandardProject.Builders.Service
{
    public class ElementBuilderBusinessEntity : ElementBuilder
    {
        public override void BuildStructure(ComponentLogic.ElementModel.Package viewModel, AddIn.EA.Framework.RepositoryManager templateRepository, BusinessEntityStandardProject itemEntity)
        {
            BuildBusinessEntityElement(viewModel, templateRepository, itemEntity);
            if (itemEntity.HasFilter)
                BuildBusinessEntityFilterElement(viewModel, templateRepository, itemEntity);
            if (itemEntity.HasKeyFilter)
                BuildBusinessEntityFilterKeyElement(viewModel, templateRepository, itemEntity);
        }
        public void BuildBusinessEntityElement(ComponentLogic.ElementModel.Package viewModel, AddIn.EA.Framework.RepositoryManager templateRepository, BusinessEntityStandardProject itemEntity)
        {
            AddIn.EA.Framework.Package templatePackage = GetTemplatePackage(templateRepository);
            AddIn.EA.Framework.Element templateBusinessEntityElement = templatePackage.GetElementByName("[entity_name]");

            //Setup the BusinessEntity package
            ComponentLogic.ElementModel.Package businessEntityPackage = GetBusinessEntityPackage(viewModel);

            //Set BusinessEntity name.
            String elementName = templateBusinessEntityElement.Name.Replace("[entity_name]", itemEntity.Name);

            //Prevent existing item before include
            businessEntityPackage.Elements.RemoveAll(it => it.Name.CompareTo(elementName) == 0);

            //Create the Entity Element
            Element businessEntityElement = BuildEntityElementFromTemplate(itemEntity, templateBusinessEntityElement, elementName);

            BindElementProperties(businessEntityElement, itemEntity);

            //Add the RuleSets description for the attributes.
            foreach (ElementModel.Attribute itemAttribute in businessEntityElement.Attributes)
            {
                Property entityProperty = itemEntity.Properties.Find(it => it.Name.CompareTo(itemAttribute.Name) == 0);
                if (entityProperty != null && entityProperty.RuleSets != null && entityProperty.RuleSets.Count > 0)
                    itemAttribute.Alias = GetRuleSetsDescription(entityProperty.RuleSets);
            }

            businessEntityPackage.Elements.Add(businessEntityElement);
        }
        public void BuildBusinessEntityFilterElement(ComponentLogic.ElementModel.Package viewModel, AddIn.EA.Framework.RepositoryManager templateRepository, BusinessEntityStandardProject itemEntity)
        {
            AddIn.EA.Framework.Package templatePackage = GetTemplatePackage(templateRepository);
            AddIn.EA.Framework.Element templateBusinessEntityParameterFilterElement = templatePackage.GetPackageByName("Parameter").GetElementByName("Filtro[entity_name]");

            ComponentLogic.ElementModel.Package businessEntityPackage = GetBusinessEntityPackage(viewModel);
            ComponentLogic.ElementModel.Package parameterPackage = GetViewModelPackage("Parameter", businessEntityPackage, true);

            String elementFilterName = templateBusinessEntityParameterFilterElement.Name.Replace("[entity_name]", itemEntity.Name);
            //Prevent existing item before include.
            parameterPackage.Elements.RemoveAll(it => it.Name.CompareTo(elementFilterName) == 0);

            //Build the filter element.
            Element businessEntityFilterElement = BuildEntityElementFromTemplate(itemEntity, templateBusinessEntityParameterFilterElement, elementFilterName);

            foreach (ComponentLogic.StandardProject.PropertyStandardProject itemProerty in itemEntity.Properties.FindAll(it => it.ComposeFilter))
                businessEntityFilterElement.Attributes.Add(CreateElementModelAttribute(itemProerty));

            parameterPackage.Elements.Add(businessEntityFilterElement);
        }
        public void BuildBusinessEntityFilterKeyElement(ComponentLogic.ElementModel.Package viewModel, AddIn.EA.Framework.RepositoryManager templateRepository, BusinessEntityStandardProject itemEntity)
        {
            AddIn.EA.Framework.Package templatePackage = GetTemplatePackage(templateRepository);
            AddIn.EA.Framework.Element templateBusinessEntityParameterKeyElement = templatePackage.GetPackageByName("Parameter").GetElementByName("Filtro[entity_name]Chave");

            ComponentLogic.ElementModel.Package businessEntityPackage = GetBusinessEntityPackage(viewModel);
            ComponentLogic.ElementModel.Package parameterPackage = GetViewModelPackage("Parameter", businessEntityPackage, true);

            String elementKeyName = templateBusinessEntityParameterKeyElement.Name.Replace("[entity_name]", itemEntity.Name);
            //Prevent existing item before include.
            parameterPackage.Elements.RemoveAll(it => it.Name.CompareTo(elementKeyName) == 0);

            //Build the filter element.
            Element businessEntityKeyElement = BuildEntityElementFromTemplate(itemEntity, templateBusinessEntityParameterKeyElement, elementKeyName);

            foreach (ComponentLogic.StandardProject.PropertyStandardProject itemProerty in itemEntity.Properties.FindAll(it => it.ComposeKey))
                businessEntityKeyElement.Attributes.Add(CreateElementModelAttribute(itemProerty));

            parameterPackage.Elements.Add(businessEntityKeyElement);
        }
        private Framework.Package GetTemplatePackage(Framework.RepositoryManager templateRepository)
        {
            return templateRepository.GetPackageByName("Servico").GetPackageByName("BusinessEntity");
        }
        private Package GetBusinessEntityPackage(ComponentLogic.ElementModel.Package viewModel)
        {
            ComponentLogic.ElementModel.Package servicoPackage = GetViewModelPackage("Servico", viewModel, true);
            ComponentLogic.ElementModel.Package businessEntityPackage = GetViewModelPackage("BusinessEntity", servicoPackage, true);
            return businessEntityPackage;
        }
        /// <summary>
        /// Create the description for the property rulesets.
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        private string GetRuleSetsDescription(List<RuleSet> list)
        {
            String description = String.Empty;
            if (list != null && list.Count > 0)
            {
                list.ForEach(it => description += "[" + it.Name + "(" + GetAttributeRuleSetsParametersDescription(it.Parameters) + ")]+");
                if (!String.IsNullOrEmpty(description))
                    description = description.Remove(description.Length - 1, 1);
            }
            return description;
        }
        /// <summary>
        /// Create the description for the ruleset parameter.
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        private string GetAttributeRuleSetsParametersDescription(List<ComponentLogic.RuleSetParameter> list)
        {
            String description = String.Empty;
            if (list != null && list.Count > 0)
            {
                list.ForEach(it => description += it.Value + ",");
                if (!String.IsNullOrEmpty(description))
                    description = description.Remove(description.Length - 1, 1);
            }
            return description;
        }

        public override void Validate()
        {
        }
    }
}
